﻿using System;

namespace CompositionPlugin.Service
{
    public interface IUIDispatcher : IRuntimeService
    {
        bool IsCurrentUIThread { get; }
        /// <summary>
        /// This method not actually 'async', it just post the method to dispatcher thread and return, no waiting
        /// </summary>
        /// <param name="method"></param>
        /// <param name="parameters"></param>
        void InvokeAsync(Delegate method, params object[] parameters);

        IAsyncResult BeginInvoke(Delegate method, AsyncCallback callback, object state, params object[] parameters);

        IAsyncResult BeginInvoke(Action method, AsyncCallback callback, object state);
        IAsyncResult BeginInvoke<T>(Action<T> method, AsyncCallback callback, object state, T arg);
        IAsyncResult BeginInvoke<T1, T2>(Action<T1, T2> method, AsyncCallback callback, object state, T1 arg1, T2 arg2);
        IAsyncResult BeginInvoke<T1, T2, T3>(Action<T1, T2, T3> method, AsyncCallback callback, object state, T1 arg1, T2 arg2, T3 arg3);
        IAsyncResult BeginInvoke<T1, T2, T3, T4>(Action<T1, T2, T3, T4> method, AsyncCallback callback, object state, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
        IAsyncResult BeginInvoke<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> method, AsyncCallback callback, object state, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
        IAsyncResult BeginInvoke<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> method, AsyncCallback callback, object state, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
        IAsyncResult BeginInvoke<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> method, AsyncCallback callback, object state, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);

        IAsyncResult BeginInvoke<TResult>(Func<TResult> method, AsyncCallback callback, object state);
        IAsyncResult BeginInvoke<T, TResult>(Func<T, TResult> method, AsyncCallback callback, object state, T arg);
        IAsyncResult BeginInvoke<T1, T2, TResult>(Func<T1, T2, TResult> method, AsyncCallback callback, object state, T1 arg1, T2 arg2);
        IAsyncResult BeginInvoke<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> method, AsyncCallback callback, object state, T1 arg1, T2 arg2, T3 arg3);
        IAsyncResult BeginInvoke<T1, T2, T3, T4, TResult>(Func<T1, T2, T3, T4, TResult> method, AsyncCallback callback, object state, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
        IAsyncResult BeginInvoke<T1, T2, T3, T4, T5, TResult>(Func<T1, T2, T3, T4, T5, TResult> method, AsyncCallback callback, object state, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
        IAsyncResult BeginInvoke<T1, T2, T3, T4, T5, T6, TResult>(Func<T1, T2, T3, T4, T5, T6, TResult> method, AsyncCallback callback, object state, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
        IAsyncResult BeginInvoke<T1, T2, T3, T4, T5, T6, T7, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, TResult> method, AsyncCallback callback, object state, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);

        object EndInvoke(Delegate method, IAsyncResult context);

        void EndInvoke(Action method, IAsyncResult context);
        void EndInvoke<T>(Action<T> method, IAsyncResult context);
        void EndInvoke<T1, T2>(Action<T1, T2> method, IAsyncResult context);
        void EndInvoke<T1, T2, T3>(Action<T1, T2, T3> method, IAsyncResult context);
        void EndInvoke<T1, T2, T3, T4>(Action<T1, T2, T3, T4> method, IAsyncResult context);
        void EndInvoke<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> method, IAsyncResult context);
        void EndInvoke<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> method, IAsyncResult context);
        void EndInvoke<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> method, IAsyncResult context);

        TResult EndInvoke<TResult>(Func<TResult> method, IAsyncResult context);
        TResult EndInvoke<T, TResult>(Func<T, TResult> method, IAsyncResult context);
        TResult EndInvoke<T1, T2, TResult>(Func<T1, T2, TResult> method, IAsyncResult context);
        TResult EndInvoke<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> method, IAsyncResult context);
        TResult EndInvoke<T1, T2, T3, T4, TResult>(Func<T1, T2, T3, T4, TResult> method, IAsyncResult context);
        TResult EndInvoke<T1, T2, T3, T4, T5, TResult>(Func<T1, T2, T3, T4, T5, TResult> method, IAsyncResult context);
        TResult EndInvoke<T1, T2, T3, T4, T5, T6, TResult>(Func<T1, T2, T3, T4, T5, T6, TResult> method, IAsyncResult context);
        TResult EndInvoke<T1, T2, T3, T4, T5, T6, T7, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, TResult> method, IAsyncResult context);
    }
}
